package com.example.common.grpc;

import com.example.common.constants.ServiceNames;
import com.example.game.proto.internal.GrpcServiceGrpc;
import io.grpc.Channel;
import io.grpc.netty.shaded.io.grpc.netty.NegotiationType;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.AbstractStub;

import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;

/**
 * @author Allen
 * @description rpc client
 * @Date 2022/9/8 14:54
 */
public class RpcClient {
    private Channel channel;
    private int failNum;
    private AbstractStub<?> blockingStub;
    private AbstractStub<?> syncStub;
    private AbstractStub<?> stub;
    private int serverId;
    private ServiceNames serverType;


    public RpcClient(int serverId, ServiceNames serverType, SocketAddress socketAddress, int grpcKeepAliveTime) {
        NettyChannelBuilder channelBuilder = NettyChannelBuilder.forAddress(socketAddress);
        this.serverId = serverId;
        this.serverType = serverType;
        channelBuilder.negotiationType(NegotiationType.PLAINTEXT)
            .keepAliveTime(grpcKeepAliveTime, TimeUnit.SECONDS)
            .keepAliveTimeout(grpcKeepAliveTime, TimeUnit.SECONDS)
            .maxInboundMessageSize(5 * 1024 * 1024)
        ;
        channel = channelBuilder.build();
    }

    public int getServerId() {
        return serverId;
    }

    public void init() {
        blockingStub = GrpcServiceGrpc.newBlockingStub(channel);
        syncStub = GrpcServiceGrpc.newFutureStub(channel);
        stub= GrpcServiceGrpc.newStub(channel);
    }

    public int getFailNum() {
        return failNum;
    }

    public void addFailNum() {
        failNum++;
    }

    public void resetFailNum() {
        failNum = 0;
    }

    public AbstractStub<?> getBlockingStub() {
        return blockingStub;
    }

    public AbstractStub<?> getSyncStub() {
        return syncStub;
    }

    public AbstractStub<?> getStub() {
        return stub;
    }

    public Channel getChannel() {
        return channel;
    }

    public ServiceNames getServerType() {
        return serverType;
    }

    @Override
    public String toString() {
        return "RpcClient{server name : " + serverType.value() + " , server id : " + getServerId() + " ,fail num : " + getFailNum() + "}";
    }

    public String toSelectString(){
        return toString() + "stub : "+ blockingStub + ", syncStub : " + syncStub + "\n";
    }
}